package course.cmsc436.medicationmanager;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import android.os.AsyncTask;
import android.util.Log;

/*
 * Class for creating, executing, and parsing a UPC lookup.
 */
public class NDCFetcher {
	private static final String NDC_FAIL = "The UPC that was given was incorrect or invalid.";
	private static String TAG = NDCFetcher.class.getSimpleName();
	private static Pattern NDC_PARSE = Pattern.compile("^3(\\d+)\\d$");
	private static Pattern ROW = Pattern.compile("<tr style=\"bottom-border: 1px solid #f6f6f6;\">(.*?)</tr>", Pattern.DOTALL);
	private static Pattern COL = Pattern.compile("<td title=\"(.*?)\".*?</td>", Pattern.DOTALL);
	private String ndc;
	private String response;
	private String result;
	/*
	 * The UPC code should be a number with either 8 or 12 digits, in string format.
	 */
	public NDCFetcher(String code) {
		Matcher m = NDC_PARSE.matcher(code);
		m.find();
		this.ndc = m.group(1);
		this.response = null;
		this.result = null;
	}
	
	private static String[] getDashPossibilities(String ndc) {
		String [] possibilities = new String[3];
		//4-4-2
		String poss1 = ndc.substring(0,4);
		poss1 += "-";
		poss1 += ndc.substring(4,8);
		poss1 += "-";
		poss1 += ndc.substring(8, 10);
		possibilities[0] = poss1;
		//5-3-2
		String poss2 = ndc.substring(0,5);
		poss2 += "-";
		poss2 += ndc.substring(5,8);
		poss2 += "-";
		poss2 += ndc.substring(8, 10);
		possibilities[1] = poss2;
		//5-4-1
		String poss3 = ndc.substring(0,5);
		poss3 += "-";
		poss3 += ndc.substring(5,9);
		poss3 += "-";
		poss3 += ndc.substring(9, 10);
		possibilities[2] = poss3;
		return possibilities;
	}
	
	private void doRequest(String code) throws MalformedURLException {
		try {
			URL url = new URL("http://www.accessdata.fda.gov/scripts/cder/ndc/results.cfm?searchfield=" + code + "&searchtype=NDCPackageCode&OrderBy=NDCPackageCode");
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			
			BufferedReader br = new BufferedReader(
				new InputStreamReader(
						new BufferedInputStream(connection.getInputStream())));
			String result = "";
			String line; 
			while((line = br.readLine()) != null) {
				result += line + "\n";
			}
			this.response = result;
		} catch (Exception e) {
			Log.e(TAG, "Could not do request", e);
		}
	}

	private void parseRequest() {
		Log.d(TAG, this.response);
		try {
			Matcher m = ROW.matcher(response);
			m.find();
			String columns = m.group(1);
			m = COL.matcher(columns);
			m.find();
			m.find();
			m.find(); //third column
			String drugname = m.group(1);
			result = drugname;
		} catch (Exception e) {
			Log.i(TAG, "Matcher broke", e);
			result = "Not found";
		}
	}
	
	public String getProductName() {
		try {
			for(String code : getDashPossibilities(this.ndc)) {
				doRequest(code);
				parseRequest();
				if(!result.equals("Not found")) {
					break;
				}
			}
		} catch (MalformedURLException e) {
			Log.e(TAG, "Invalid URL given", e);
		}
		return result;
	}
	
	public static AsyncTask<String, Void, String> doAsync(String s, final FetchCompleteListener fcl) {
		Log.d(TAG, s);
		return new AsyncTask<String, Void, String>(){

			@Override
			protected String doInBackground(String... params) {
				try {
					NDCFetcher f = new NDCFetcher(params[0]);
					return f.getProductName();
				} catch (Exception e) {
					Log.e(TAG, "Error fetching name", e);
					return "ERROR";
				}
			}
			
			@Override
			protected void onPostExecute(String result) {
				fcl.onFetchComplete(result);
			}
		}.execute(s);
	}
	
	public interface FetchCompleteListener {
		void onFetchComplete(String desc);
	};

}
